package co.edu.unal.satacredito.mediation;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import co.edu.unal.satacredito.database.administration.ejb.BrandDaoEJBLocal;
import co.edu.unal.satacredito.database.administration.ejb.EstablishmentDaoEJBLocal;
import co.edu.unal.satacredito.database.administration.ejb.FileDaoEJBLocal;
import co.edu.unal.satacredito.database.administration.exceptions.DAOException;
import co.edu.unal.satacredito.database.constants.FileLogConstants;
import co.edu.unal.satacredito.database.entity.FileLog;
import co.edu.unal.satacredito.infrastructure.dto.HistoricLoadDTO;
import co.edu.unal.satacredito.infrastructure.dto.RealLoadDTO;

/**
 * Session Bean implementation class FileLoadServiceEJB
 */
@Stateless
public class FileLoadEJB implements FileLoadEJBRemote, FileLoadEJBLocal {

	private final static String COMPLETED = "Completado";
	private static final String LOADING = "Cargando...";
	private static final String NOT_DATE = "----";
	private static final String COMPLETED_NOT_INIT_DATE = "Completado, Fecha de inicio anterior a la consulta";

	private static final String INIT_LOAD_DESCRIPTION = "Inicio de carga";
	private static final String END_LOAD_DESCRIPTION = "Fin de carga";
	private static final String NOT_BRAND_EXIST = "La marca asociada no existe";
	private static final String NOT_ESTABLISHMENT_EXIST = "El establecimiento asociado no existe";
	private static final String NOT_BRAND = "No hay marca asociada";
	private static final String NOT_ESTABLISHMENT = "No hay establecimiento asociado";
	
	@EJB
	private FileDaoEJBLocal fileDaoEJBLocal;

	@EJB
	private BrandDaoEJBLocal brandDaoEJBLocal;

	@EJB
	private EstablishmentDaoEJBLocal establishmentDaoEJBLocal;

	/**
	 * Default constructor.
	 */
	public FileLoadEJB() {
	}

	private List<FileLog> getFiles(Date initDate, Date endDate) {
		try {
			return fileDaoEJBLocal.findByDate(initDate, endDate);
		} catch (DAOException e) {
			return new ArrayList<FileLog>();
		}
	}

	private String getNameBrand(String brandId) {
		try {
			return brandDaoEJBLocal.findBrandById(brandId).getBrandName();
		} catch (DAOException e) {
			return NOT_BRAND;
		} catch (NullPointerException e) {
			return NOT_BRAND_EXIST;
		}
	}

	private String getNameEstablishment(String brandId) {
		try {
			return establishmentDaoEJBLocal.findEstablishmentById(brandId)
					.getNameEstablishment();
		} catch (DAOException e) {
			return NOT_ESTABLISHMENT;
		} catch (NullPointerException e) {
			return NOT_ESTABLISHMENT_EXIST;
		}
	}

	@Override
	public List<HistoricLoadDTO> getHistoric(Date initDate, Date endDate) {
		List<HistoricLoadDTO> historicList = new ArrayList<HistoricLoadDTO>();
		List<FileLog> fileList = getFiles(initDate, endDate);
		while (!fileList.isEmpty()) {
			
			// To check if there is an initial event and an final event to a
			// same file
			int i = 1;
			while (i < fileList.size()) {
				HistoricLoadDTO h = new HistoricLoadDTO();
				if (fileList.get(0).getFileId()
						.equals(fileList.get(i).getFileId())) {
					h.setFileId(fileList.get(0).getFileId()+"");
					h.setStartDate(fileList.get(0).getDate().toString());
					h.setEndDate(fileList.get(i).getDate().toString());
					h.setBrand(getNameBrand(fileList.get(0).getBrand()+""));
					h.setEstablishment(getNameEstablishment(fileList.get(0)
							.getEstablishment()+""));
					h.setState(COMPLETED);
					historicList.add(h);
					fileList.remove(i);
					fileList.remove(0);
				} else {
					i++;
				}
			}

			if (!fileList.isEmpty()) {
				// To check if it's an initiation event
				HistoricLoadDTO h = new HistoricLoadDTO();
				if (fileList.get(0).getState() == FileLogConstants.STATE_INIT) {
					h.setFileId(fileList.get(0).getFileId()+"");
					h.setStartDate(fileList.get(0).getDate().toString());
					h.setEndDate(NOT_DATE);
					h.setBrand(getNameBrand(fileList.get(0).getBrand()+""));
					h.setEstablishment(getNameEstablishment(fileList.get(0)
							.getEstablishment()+""));
					h.setState(LOADING);
					historicList.add(h);
					fileList.remove(0);
				} // When it's a final event
				else {
					h.setFileId(fileList.get(0).getFileId()+"");
					h.setStartDate(NOT_DATE);
					h.setEndDate(fileList.get(0).getDate().toString());
					h.setBrand(getNameBrand(fileList.get(0).getBrand()+""));
					h.setEstablishment(getNameEstablishment(fileList.get(0)
							.getEstablishment()+""));
					h.setState(COMPLETED_NOT_INIT_DATE);
					historicList.add(h);
					fileList.remove(0);
				}
			}
		}
		return historicList;
	}

	@Override
	public List<RealLoadDTO> getReal() {
		List<RealLoadDTO> realList = new ArrayList<RealLoadDTO>();
		Calendar finalDate = Calendar.getInstance();
		Calendar initDate =(Calendar) finalDate.clone();
		initDate.set(Calendar.SECOND, finalDate.get(Calendar.SECOND)-1);

		List<FileLog> list = getFiles(initDate.getTime(), finalDate.getTime());
		System.out.println(list.size());
		for (FileLog f : list) {
			RealLoadDTO r = new RealLoadDTO();
			r.setFileId(f.getFileId()+"");
			r.setBrand(getNameBrand(f.getBrand()+""));
			r.setDate(f.getDate().toString());
			r.setDescription(getDescription(f.getState()));
			r.setEstablishment(getNameEstablishment(f.getEstablishment()+""));
			realList.add(r);
		}
		System.out.println(realList.size());
		return realList;

	}

	private String getDescription(int state) {
		if(state == FileLogConstants.STATE_INIT)
			return INIT_LOAD_DESCRIPTION;
		else
			return END_LOAD_DESCRIPTION;
	}

}
